SpringApplication类提供了一种快捷方式,用于从main()
方法启动Spring应用。多数情况下,你只需要将该任务委托给SpringApplication.run
静态方法:
public static void main(String[] args){
SpringApplication.run(MySpringConfiguration.class, args);
}
当应用启动时,你应该会看到类似下面的东西:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: v1.4.1.RELEASE
2013-07-31 00:08:16.117 INFO 56603 --- [ main] o.s.b.s.app.SampleApplication : Starting SampleApplication v0.1.0 on mycomputer with PID 56603 (/apps/myapp.jar started by pwebb)
2013-07-31 00:08:16.166 INFO 56603 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@6e5a8246: startup date [Wed Jul 31 00:08:16 PDT 2013]; root of context hierarchy
2014-03-04 13:09:54.912 INFO 41370 --- [ main] .t.TomcatEmbeddedServletContainerFactory : Server initialized with port: 8080
2014-03-04 13:09:56.501 INFO 41370 --- [ main] o.s.b.s.app.SampleApplication : Started SampleApplication in 2.992 seconds (JVM running for 3.658)
默认情况下会显示INFO级别的日志信息,包括一些相关的启动详情,比如启动应用的用户等。
如果应用启动失败,注册的FailureAnalyzers
就有机会提供一个特定的错误信息,及具体的解决该问题的动作。例如,如果在8080
端口启动一个web应用,而该端口已被占用,那你应该可以看到类似如下的内容:
***************************
APPLICATION FAILED TO START
***************************
Description:
Embedded servlet container failed to start. Port 8080 was already in use.
Action:
Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.
注 Spring Boot提供很多的FailureAnalyzer
实现,你自己实现也很容易。
如果没有可用于处理该异常的失败分析器(failure analyzers),你需要展示完整的auto-configuration报告以便更好的查看出问题的地方,因此你需要启用org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer
的debug属性,或开启DEBUG日志级别。
例如,使用java -jar
运行应用时,你可以通过如下命令启用debug
属性:
$ java -jar myproject-0.0.1-SNAPSHOT.jar --debug
通过在classpath下添加一个banner.txt
或设置banner.location
来指定相应的文件可以改变启动过程中打印的banner。如果这个文件有特殊的编码,你可以使用banner.encoding
设置它(默认为UTF-8)。除了文本文件,你也可以添加一个banner.gif
,banner.jpg
或banner.png
图片,或设置banner.image.location
属性。图片会转换为字符画(ASCII art)形式,并在所有文本banner上方显示。
在banner.txt中可以使用如下占位符:
变量 | 描述 |
---|---|
${application.version} | MANIFEST.MF中声明的应用版本号,例如Implementation-Version: 1.0 会打印1.0 |
${application.formatted-version} | MANIFEST.MF中声明的被格式化后的应用版本号(被括号包裹且以v作为前缀),用于显示,例如(v1.0 ) |
${spring-boot.version} | 当前Spring Boot的版本号,例如1.4.1.RELEASE |
${spring-boot.formatted-version} | 当前Spring Boot被格式化后的版本号(被括号包裹且以v作为前缀), 用于显示,例如(v1.4.1.RELEASE ) |
${Ansi.NAME}(或${AnsiColor.NAME},${AnsiBackground.NAME}, ${AnsiStyle.NAME}) | NAME代表一种ANSI编码,具体详情查看AnsiPropertySource |
${application.title} | MANIFEST.MF 中声明的应用title,例如Implementation-Title: MyApp 会打印MyApp |
注 如果想以编程的方式产生一个banner,可以使用SpringBootApplication.setBanner(…)
方法,并实现org.springframework.boot.Banner
接口的printBanner()
方法。
你也可以使用spring.main.banner-mode
属性决定将banner打印到何处,System.out
(console
),配置的logger(log
)或都不输出(off
)。
打印的banner将注册成一个名为springBootBanner
的单例bean。
注 YAML会将off
映射为false
,如果想在应用中禁用banner,你需要确保off
添加了括号:
spring:
main:
banner-mode: "off"
如果默认的SpringApplication
不符合你的口味,你可以创建一个本地实例并对它进行自定义。例如,想要关闭banner你可以这样写:
public static void main(String[] args) {
SpringApplication app = new SpringApplication(MySpringConfiguration.class);
app.setBannerMode(Banner.Mode.OFF);
app.run(args);
}
注:传递给SpringApplication
的构造器参数将作为spring beans的配置源,多数情况下,它们是一些@Configuration
类的引用,但也可能是XML配置或要扫描包的引用。
你也可以使用application.properties
文件来配置SpringApplication
,具体参考24. Externalized 配置,访问SpringApplication Javadoc可获取完整的配置选项列表.
如果需要创建一个分层的ApplicationContext
(多个具有父子关系的上下文),或只是喜欢使用流式(fluent)构建API,那你可以使用SpringApplicationBuilder。
SpringApplicationBuilder允许你以链式方式调用多个方法,包括parent和child方法,这样就可以创建多层次结构,例如:
new SpringApplicationBuilder()
.sources(Parent.class)
.child(Application.class)
.bannerMode(Banner.Mode.OFF)
.run(args);
注:创建ApplicationContext层次时有些限制,比如,Web组件必须包含在子上下文中,并且父上下文和子上下文使用相同的Environment,具体参考SpringApplicationBuilder javadoc。
除了常见的Spring框架事件,比如ContextRefreshedEvent,SpringApplication
也会发送其他的application事件。
注 有些事件实际上是在ApplicationContext
创建前触发的,所以你不能在那些事件(处理类)中通过@Bean
注册监听器,只能通过SpringApplication.addListeners(…)
或SpringApplicationBuilder.listeners(…)
方法注册。如果想让监听器自动注册,而不关心应用的创建方式,你可以在工程中添加一个META-INF/spring.factories
文件,并使用org.springframework.context.ApplicationListener
作为key指向那些监听器,如下:
org.springframework.context.ApplicationListener=com.example.project.MyListener
应用运行时,事件会以下面的次序发送:
ApplicationStartedEvent
。ApplicationEnvironmentPreparedEvent
。ApplicationPreparedEvent
。ApplicationReadyEvent
,表示应用准备好接收请求了。ApplicationFailedEvent
。注 通常不需要使用application事件,但知道它们的存在是有用的(在某些场合可能会使用到),比如,在Spring Boot内部会使用事件处理各种任务。
SpringApplication
将尝试为你创建正确类型的ApplicationContext
,默认情况下,根据你开发的是否为web应用决定使用AnnotationConfigApplicationContext
或AnnotationConfigEmbeddedWebApplicationContext
。
用于确定是否为web环境的算法相当简单(判断是否存在某些类),你可以使用setWebEnvironment(boolean webEnvironment)
覆盖默认行为。
通过调用setApplicationContextClass(…)
,你可以完全控制ApplicationContext
的类型。
注 在Junit测试中使用SpringApplication
,调用setWebEnvironment(false)
是很有意义的。
如果需要获取传递给SpringApplication.run(…)
的应用参数,你可以注入一个org.springframework.boot.ApplicationArguments
类型的bean。ApplicationArguments
接口即提供对原始String[]
参数的访问,也提供对解析成option
和non-option
参数的访问:
import org.springframework.boot.*
import org.springframework.beans.factory.annotation.*
import org.springframework.stereotype.*
@Component
public class MyBean {
@Autowired
public MyBean(ApplicationArguments args) {
boolean debug = args.containsOption("debug");
List<String> files = args.getNonOptionArgs();
// if run with "--debug logfile.txt" debug=true, files=["logfile.txt"]
}
}
注 Spring Boot也会注册一个包含Spring Environment
属性的CommandLinePropertySource
,这就允许你使用@Value
注解注入单个的应用参数。
如果需要在SpringApplication
启动后执行一些特殊的代码,你可以实现ApplicationRunner
或CommandLineRunner
接口,这两个接口工作方式相同,都只提供单一的run
方法,该方法仅在SpringApplication.run(…)
完成之前调用。
CommandLineRunner
接口能够访问string数组类型的应用参数,而ApplicationRunner
使用的是上面描述过的ApplicationArguments
接口:
import org.springframework.boot.*
import org.springframework.stereotype.*
@Component
public class MyBean implements CommandLineRunner {
public void run(String... args) {
// Do something...
}
}
如果某些定义的CommandLineRunner
或ApplicationRunner
beans需要以特定的顺序调用,你可以实现org.springframework.core.Ordered
接口或使用org.springframework.core.annotation.Order
注解。
为确保ApplicationContext
在退出时被平静的(gracefully)关闭,每个SpringApplication
都会注册一个JVM的shutdown钩子,所有标准的Spring生命周期回调(比如DisposableBean
接口或@PreDestroy
注解)都能使用。
此外,如果想在应用结束时返回特定的退出码(exit code),这些beans可以实现org.springframework.boot.ExitCodeGenerator
接口。
通过设置spring.application.admin.enabled
属性可以启用管理相关的(admin-related)特性,这将暴露SpringApplicationAdminMXBean到平台的MBeanServer
,你可以使用该特性远程管理Spring Boot应用,这对任何service包装器(wrapper)实现也有用。
注 通过local.server.port
可以获取该应用运行的HTTP端口。启用该特性时需要注意MBean会暴露一个方法去关闭应用。